/**
 * @brief 2.5.2 auto类型说明符
 * auto类型说明符，用它就能让编译器替我们去分析表达式所属的类型。
 * auto让编译器通过初始值来推算变量的类型。显然，auto定义的变量必须有初始值。
 * @param argc 
 * @param argv 
 * @return int 
 */

int main(int argc, char const *argv[])
{
    int val1 = 1, val2 = 2;
    auto item = val1 + val2; // 此处编译器将根据val1和val2相加的结果来推断item的类型

    auto i = 0, *p = &i;

    // auto一般会忽略掉顶层const
    const int ci = i, &cr = ci;
    auto b = ci; // b是一個整数，因为auto忽略了顶层const
    auto c = cr; // b是一個整数
    auto d = &i; // d是一个整型指针（整数的地址就是指向整数的指针）
    auto e = &ci; // e是一个指向整数常量的指针（对常量对象取地址是个）

    // 如果希望编译器推断出auto类型是一个顶层const，需要明确指出
    const auto f = ci; // 由于忽略顶层const的缘故，所以ci的推演类型是int；又由于在auto前明确加了const，所以f是const int

    // 还可以将引用的类型设为auto，此时原来的初始化规则仍然适用
    auto &g = ci; // g是一个整型常量引用，绑定到ci
    // auto &h = 42; // 错误，不能为非常量引用绑定字面值
    const auto &j = 42; // 正确，可以为常量引用绑定字面值

    return 0;
}
